package com.say.utils.weixin;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.say.framework.core.util.HttpRemote;


/**
 *
 * 公众平台通用接口工具类
 *
 */
public class WeixinUtil {
	
    private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);

    public  static String APPID = "wxa959dce433c0fdb7";

    public  static String APPSECRET = "6e1d554e4a1167330f2f6ef2179b4d75";

    public  static String TOKEN ="weixin";

    public  static String TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token";//获取token

    public  static String JSAPI_TICKET_URL="https://api.weixin.qq.com/cgi-bin/ticket/getticket";//获取jsapi_ticket
    
    public static Map<String,Object> accessTokenMap=new HashMap<String, Object>();
    
    public static Map<String,Object> jsApiTicketMap=new HashMap<String, Object>();
    
    
    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject =  JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("Weixin server connection timed out.");
            return null;
        } catch (Exception e) {
            log.error("https request error:{}", e);
            return null;
        }
        return jsonObject;
    }

    public static String httpRequestString(String requestUrl, String requestMethod, String outputStr) {
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
        } catch (ConnectException ce) {
            log.error("Weixin server connection timed out.");
        } catch (Exception e) {
            log.error("https request error:{}", e);
        }
        return buffer.toString();
    }



    /**
     * 根据内容类型判断文件扩展名
     *
     * @param contentType 内容类型
     * @return
     */
    public static String getFileEndWitsh(String contentType) {
        String fileEndWitsh = "";
        if ("image/jpeg".equals(contentType))
            fileEndWitsh = ".jpg";
        else if ("image/jpg".equals(contentType))
            fileEndWitsh = ".jpg";
        else if ("image/png".equals(contentType))
            fileEndWitsh = ".png";
        else if ("audio/mpeg".equals(contentType))
            fileEndWitsh = ".mp3";
        else if ("audio/amr".equals(contentType))
            fileEndWitsh = ".amr";
        else if ("video/mp4".equals(contentType))
            fileEndWitsh = ".mp4";
        else if ("video/mpeg4".equals(contentType))
            fileEndWitsh = ".mp4";
        return fileEndWitsh;
    }
    
    /**
     * 获取access_token
     *
     */
    public static String getAccessToken() throws Exception {
        //此请求为https的get请求，返回的数据格式为{"access_token":"ACCESS_TOKEN","expires_in":7200}
    	if(accessTokenMap!=null && accessTokenMap.containsKey("access_token")) {
    		long expires_in=Long.parseLong(accessTokenMap.get("expires_in").toString());
    		if(new Date().getTime()<=expires_in) {
    			//未过期了。
    			return accessTokenMap.get("access_token").toString();
    		}
    	}
        Map<String,Object>  map = new  HashMap<String,Object>();
        map.put("grant_type", "client_credential");
        map.put("appid", APPID);
        map.put("secret", APPSECRET);
        String  result=HttpRemote.GETMethod(TOKEN_URL, map);
        log.info("getAccessToken--返回"+result);
        JSONObject json = JSON.parseObject(result);
        accessTokenMap.put("access_token", json.getString("access_token"));
        accessTokenMap.put("expires_in", new Date().getTime()+json.getLong("expires_in")-500);//-500，保留够的时间
        return getAccessToken();
    }
    
    /**
     * 获取jsapi_ticket
     *
     */
    public static String getJsApiTicket() throws Exception {
    	//此请求为https的get请求，返回的数据格式为{"ticket":"ACCESS_TOKEN","expires_in":7200}
    	if(jsApiTicketMap!=null && jsApiTicketMap.containsKey("ticket")) {
    		long expires_in=Long.parseLong(jsApiTicketMap.get("expires_in").toString());
    		if(new Date().getTime()<=expires_in) {
    			//未过期了。
    			return jsApiTicketMap.get("ticket").toString();
    		}
    	}
        Map<String,Object>  map = new  HashMap<String,Object>();
        map.put("type", "jsapi");
        map.put("access_token", getAccessToken());
        String  result=HttpRemote.GETMethod(JSAPI_TICKET_URL, map);
        log.info("getjsAccessToken--返回"+result);
        //使用FastJson将Json字符串解析成Json对象
        JSONObject json = JSON.parseObject(result);
        jsApiTicketMap.put("ticket", json.getString("ticket"));
        jsApiTicketMap.put("expires_in", new Date().getTime()+json.getLong("expires_in")-500);//-500，保留够的时间
        return getJsApiTicket();
    }

    public static Map<String,Object> getSignature(String url) throws Exception{
        Map<String,Object> map  =new HashMap<String, Object>();
        String jsApiTicket=getJsApiTicket();
        if(jsApiTicket!=null){
            String timestamp = Long.toString(System.currentTimeMillis()/1000);
            String noncestr = UUID.randomUUID().toString();
            // 排序
            String sortString =
                    "jsapi_ticket=" + jsApiTicket +
                            "&noncestr=" + noncestr +
                            "&timestamp=" + timestamp +
                            "&url=" +url;
            // 加密
            String	signature =  new SHA1Util().sha1(sortString);
            map.put("appId",APPID);
            map.put("timestamp", timestamp);
            map.put("noncestr", noncestr);
            map.put("signature", signature);
        }
        return map;
    }
}
